package de.haw.adt.implementation;

import static de.haw.adt.implementation.Values.FEET_IN_METERS;
import static de.haw.adt.implementation.Values.KILO;
import static de.haw.adt.implementation.Values.METER_IN_NANOMETER;
import de.haw.adt.interfaces.ILength;

final class Length extends AbstractPhysicalScalar implements ILength {

	private final double meters;

	// OBJECT CREATION
	private Length(double meters) {
		this.meters = meters;
	}
	
	@Override
	double getValue() {
		return meters;
	}
	
	public double getFt() {
		return meters / FEET_IN_METERS;
	}

	public double getM() {
		return meters;
	}

	public ILength inverse() {
		return new Length(this.getM() * -1);
	}

	public ILength add(ILength length) {
		return valueOf(this.getM() + length.getM());
	}

	public ILength sub(ILength length) {
		return valueOf(this.getM() - length.getM());
	}

	// STANDARD HETEROGENOUS ARITHMETIC
	public ILength mul(double factor) {
		return valueOf(this.getM() * factor);
	}

	public ILength div(double factor) {
		return valueOf(this.getM() / factor);
	}

	public double div(ILength length) {
		return (this.getM() / length.getM());
	}

	public int compareTo(ILength length) {
		return Double.compare(this.getM(), length.getM());
	}

	@Override
	public boolean equals(Object o) {
		if (o == this)
			return true;
		if (!(o instanceof Length))
			return false;
		return this.compareTo((Length) o) == 0;
	}

	@Override
	public String toString() {
		return String.format("%.2d m", this.getM());
	}

	public double getKm() {
		return meters / KILO;
	}

	public double getNm() {
		return meters * METER_IN_NANOMETER;
	}
	
	public static Length valueOf(double meters) {
		return new Length(meters);
	}
}
